package com.sbck.cs3.MyClass;

import android.graphics.Color;
import android.util.Log;

import com.sbck.cs3.MyGlobal;
import com.sbck.cs3.UNITINFO;
import com.sbck.cs3.UNITSTATUS;

import org.greenrobot.eventbus.EventBus;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.text.DecimalFormat;

public class RecvDataThread extends Thread {
    public Socket cSocket;

    byte[] RxData = new byte[1038];
    public RecvDataThread(Socket socket)
    {
        cSocket = socket;
    }
    @Override
    public void run() {
        Log.i("RecvDataThread","开始接收收据!");



        int DataLong;
        while (true)
        {
            try
            {
                InputStream inputStream = null;
                inputStream = cSocket.getInputStream();
                byte[] buff = new byte[1024];
                int len = -1;

                while ((len = inputStream.read(buff)) != -1)
                {
                    Log.i("RecvDataThread","收到数据长度:="+ len );

                    if(buff[0] ==  (byte)0xAB && buff[1] ==  (byte)0xBB && buff[2] ==  (byte) 0xCB && buff[3] ==  (byte) 0xDB )
                    {
                        DataLong = buff[4] * 256 + buff[5];
                        System.arraycopy(buff,6,RxData,0,DataLong);

                        if(MyGlobal.unitinfo.DTU.get() != null) {
                            DealRecv();
                        }
                    }
                }
            }
            catch (SocketTimeoutException e)
            {
                Log.i("rqp-RecvDataThread-tcp", "读超时, 超时计次:"+ MyGlobal.TimeoutCount++);
                if(MyGlobal.TimeoutCount > 60)
                {
                    MyMessage myMessage = new MyMessage(MessageCategory.SocketError);
                    myMessage.messageType = MessageType.HeartTimeout;
                    MyGlobal.HeartCount = 0;
                    EventBus.getDefault().post(myMessage);
                }
            }
            catch (SocketException e)
            {
                MyGlobal.AddLog("Socket服务("+cSocket.getRemoteSocketAddress()+")连接异常,"+e.getMessage(),Color.RED);


                MyGlobal.AddLog("出现Socket连接异常,请重启程序",Color.RED);
                Log.i("rqp-RecvDataThread-SocketException", e.getMessage());
                break;
            } catch (IOException e) {
                MyGlobal.AddLog("Socket服务(\"+cSocket.getRemoteSocketAddress()+\")连接异常,"+e.getMessage(),Color.RED);
                MyGlobal.AddLog("出现Socket连接异常,请重启程序",Color.RED);
                Log.i("rqp-RecvDataThread-IOException", e.getMessage());
                break;
            }
        }
    }

    private int Byte2Int(Byte b)
    {
        return 0xff & b;
    }
    private void DealRecv()
    {
        long RecvDtuID = 0;
        int TempData = 0;
        UNITSTATUS unitstatus = MyGlobal.unitstatus;
        UNITINFO unitinfo = MyGlobal.unitinfo;
        int[]  rtuNo = new int[4];
        for (int i = 0; i < 4; i++) {
            if(RxData[i] >= 0)
                rtuNo[i] = RxData[i];
            else
            {
                rtuNo[i] = (int)(RxData)[i]&0x7f + 128;
            }
        }

        Boolean HasFired = false;
        RecvDtuID += rtuNo[0] * (int)(0X1000000);
        RecvDtuID += rtuNo[1] * 0X10000;
        RecvDtuID += rtuNo[2] * 0X100;
        RecvDtuID += rtuNo[3];
        //          string[] ChStatus = new string[50];

        int dtu = Integer.parseInt(MyGlobal.unitinfo.DTU.get());
        if(RecvDtuID != dtu)
            return;
        Log.i("rqp-RecvDataThread-DealRecv", "------------------收到当前设备数据");
        MyGlobal.ReceiveCount ++;
        MyGlobal.TimeoutCount = 0;
        MyMessage myMessage = new MyMessage(MessageCategory.SocketReceive);
        switch (RxData[4]) {
                // 心跳
            case (byte) 0xA1: {
                MyGlobal.HeartCount ++;
                myMessage.messageType = MessageType.Heart;
                TempData = Byte2Int(RxData[5]) * 256;
                TempData += Byte2Int(RxData[6]);
                unitstatus.DYA = TempData * 0.01f;//电压a

                TempData = Byte2Int(RxData[7]) * 256;
                TempData += Byte2Int(RxData[8]);
                unitstatus.DYB = TempData * 0.1f;//电压b

                TempData = Byte2Int(RxData[9]) * 256;
                TempData += Byte2Int(RxData[10]);
                unitstatus.DYC = TempData;// 电压c


                TempData = Byte2Int(RxData[11]) * 256;
                TempData += Byte2Int(RxData[12]);
                unitstatus.DLA = TempData;//电流a


                TempData = Byte2Int(RxData[13])  * 256;
                TempData += Byte2Int(RxData[14]);
                unitstatus.DLB = TempData;// 电流b

                TempData = Byte2Int(RxData[15]) * 256;
                TempData += Byte2Int(RxData[16]);
                unitstatus.DLC = TempData;// 电流c

                //电度数
                long energy = RxData[17] * 16777216;
                energy += RxData[18] * 65536;
                energy += RxData[19] * 256;
                energy += RxData[20];
                unitstatus.DN = energy * 0.01f;//电度数

                //系统上电状态
                if (RxData[21] == 1)
                    unitstatus.SDZT = true;//
                else
                    unitstatus.SDZT = false;//

                unitstatus.WorkMode = RxData[22]; //工作模式

                unitstatus.FJPL = RxData[23]; //风机频率

                if (RxData[24] == 1)  //加热状态
                    unitstatus.JRZT = true;
                else
                    unitstatus.JRZT = false;


                if (RxData[25] == 1)  //水泵状态
                    unitstatus.SBZT = true;
                else
                    unitstatus.SBZT = false;

                if (RxData[26] == 1)  //混合阀1状态
                    unitstatus.HHF1ZT = true;
                else
                    unitstatus.HHF1ZT = false;

                if (RxData[27] == 1)  //混合阀2状态
                    unitstatus.HHF2ZT = true;
                else
                    unitstatus.HHF2ZT = false;

                if (RxData[28] == 1)  //放水阀状态
                    unitstatus.PSFZT = true;
                else
                    unitstatus.PSFZT = false;

                if (RxData[29] == 1)  //俯仰状态
                    unitstatus.FYZT = true;
                else
                    unitstatus.FYZT = false;

                unitstatus.FWJ = Byte2Int(RxData[30]) - 10;

                if (RxData[31] == 1)  //防雨顶状态
                    unitstatus.FYDZT = true;
                else
                    unitstatus.FYDZT = false;

                unitstatus.CHJYL = Byte2Int(RxData[32]); //催化剂余量

                unitstatus.FDJSYYL = Byte2Int(RxData[33]); //发电机剩余油量

                unitstatus.SYSL = Byte2Int(RxData[34]); //剩余水量

                TempData =Byte2Int(RxData[35])  * 256;
                TempData += Byte2Int(RxData[36]);
                int t1 = (TempData - 20000) / 256;
                int t2 = (TempData - 20000) % 256;
                unitstatus.ZKBWD = t1 + t2 * 0.01; //主控板温度

                TempData = Byte2Int(RxData[37]) * 256;
                TempData += Byte2Int(RxData[38]);
                unitstatus.SysWorkTime = TempData;//系统工作时间

                TempData = Byte2Int(RxData[39]) * 256;
                TempData += Byte2Int(RxData[40]);
                unitstatus.YTWorkTime = TempData;//焰条工作时间

                TempData = Byte2Int(RxData[41]) * 256;
                TempData += Byte2Int(RxData[42]);
                unitstatus.JRWorkTime = TempData;//加热工作时间

                TempData = Byte2Int(RxData[43]) * 256;
                TempData += Byte2Int(RxData[44]);
                unitstatus.O3WorkTime = TempData;//消除臭氧工作时间



                if (RxData[45] == 1)
                    unitstatus.FSZT = true;//风扇状态
                else
                    unitstatus.FSZT = false;

                if (RxData[46] == 1)
                    unitstatus.AlarmStop = true;//急停状态
                else
                    unitstatus.AlarmStop = false;

                unitstatus.PowerMode = Byte2Int(RxData[47]); // 供电方式  0无选择 1: 市电  2:发电机

                unitstatus.StartMode = Byte2Int(RxData[48]); //启动方式  0:软件启动 1:硬件启动

                unitstatus.FJCloseRemainTime = Byte2Int(RxData[49]) * 60; //风机延时关闭剩余时间


                TempData = Byte2Int(RxData[50]) * 256;
                TempData += Byte2Int(RxData[51]);
                unitstatus.BPQPL = TempData * 0.01f;  // 变频器频率

                unitstatus.BSFS = Byte2Int(RxData[52]); //播撒方式 0停用，1半旋转,2全旋转

                unitstatus.AllowDeviceCtrl = Byte2Int(RxData[53]); //允许硬件控制

                unitstatus.DevcePowerMode = Byte2Int(RxData[54]); //硬件启动时的供电方式

                String workModeStr ;

                if(unitstatus.FYZT)
                {
                    workModeStr = "消除臭氧";
                }
                else
                {
                    if(unitstatus.FWJ == 45)
                    {
                        workModeStr = "除霾加热";
                    }
                    if (unitstatus.FWJ == 90)
                    {
                        workModeStr = "增雨";
                    }
                    else
                    {
                        workModeStr = "待机";
                    }
                }

                String fw_WorkMode = "";
                if (unitstatus.BSFS == 0)
                    fw_WorkMode = "停用";
                else if(unitstatus.BSFS == 1)
                    fw_WorkMode = "半旋转";
                else if(unitstatus.BSFS == 2)
                    fw_WorkMode = "全旋转";

                String devicePwoerModestr = "";
                if (unitstatus.DevcePowerMode == 1)
                    devicePwoerModestr = "市电";
                else if (unitstatus.DevcePowerMode == 1)
                    devicePwoerModestr = "发电机";

                break;
            }
            // 系统上电
            case (byte) 0xA2: {
                myMessage.messageType = MessageType.SysPower;
                if (1 == RxData[5]) {
                    unitstatus.SDZT = true;
                } else {
                    unitstatus.SDZT = false;
                    unitstatus.SysWorkTime = 0;
                }
                break;
            }
            // 防雨顶
            case (byte) 0xA3: {
                myMessage.messageType = MessageType.FYD;
                unitstatus.FYDZT = 1 == RxData[5];
                break;
            }
            // 风机控制
            case (byte) 0xA4: {
                myMessage.messageType = MessageType.FJPL;
                unitstatus.FJPL = Byte2Int(RxData[5]);
                break;
            }
            // 加热控制
            case (byte) 0xA5:
                myMessage.messageType = MessageType.JRKZ;
                unitstatus.JRMode = Byte2Int(RxData[5]);
                unitstatus.JRZT = 1 == unitstatus.JRMode;
                break;

            //增雨控制
            case (byte) 0xA6:
                myMessage.messageType = MessageType.FireReset;
                for (int j = 1; j < 25; j++)
                {
                    MyGlobal.tChStateArrayList.get(j - 1).Status = 0;
                }
                break;
            //增雨控制
            case (byte) 0xA7:
                myMessage.messageType = MessageType.FireState;
                for (int j = 0; j < 24; j++) {
                    if (RxData[5 + j] == 2) {
                        MyGlobal.tChStateArrayList.get(j).Status = 4;
                    }
                    if (RxData[5 + j] == 1) {
                        MyGlobal.tChStateArrayList.get(j).Status = 1;
                        MyGlobal.tChStateArrayList.get(j).TotalTime = 600;
                        MyGlobal.tChStateArrayList.get(j).IsCold = true;
                    }
                    if (RxData[5 + j] == 0) {
                        MyGlobal.tChStateArrayList.get(j).Status = 3;
                    }
                }
                break;
            //点火结果
            case (byte) 0xA8:
                myMessage.messageType = MessageType.FireLight;
                if(RxData[5] == 1)
                {
                    MyGlobal.AddLog(RxData[6] + "号焰条点火成功!",Color.BLUE);
                }
                else
                {
                    MyGlobal.AddLog(RxData[6] + "号焰条点火失败!",Color.RED);
                }
                break;
            // 燃气炮方位角 0xA9
            case (byte) 0xA9://
            {
                myMessage.messageType = MessageType.FWJ;
                unitstatus.FWJ = Byte2Int(RxData[5]);// 方位
                unitstatus.FWJ -= 10;
                break;
            }
            //俯仰状态(垂直/倾斜) 0XAA
            case (byte) 0xAA://
            {
                myMessage.messageType = MessageType.FYJZT;
                unitstatus.FYZT = RxData[5]==1;//俯仰状态 0:垂直 1:倾斜
                break;
            }
            // 水泵 AB
            case (byte)0xAB://水泵
            {
                myMessage.messageType = MessageType.SB;
                unitstatus.SBZT = 1 == RxData[5];
                break;
            }
            //混合阀1 AC
            case (byte)0xAC://混合阀1
                myMessage.messageType = MessageType.HHF1;
                unitstatus.HHF1ZT = RxData[5] == 1;
                break;
            //混合阀1 AC
            case (byte)0xAD://混合阀2
                myMessage.messageType = MessageType.HHF2;
                unitstatus.HHF2ZT = RxData[5] == 1;
                break;
            //region 排水阀 AE
            case (byte)0xAE://  排水阀
            {
                myMessage.messageType = MessageType.PSF;
                unitstatus.PSFZT = RxData[5] == 1;
                break;
            }
            //急停状态
            case (byte)0xAF://  急停状态
            {
                myMessage.messageType = MessageType.AlarmStop;
                unitstatus.AlarmStop = RxData[5] == 1;
                break;
            }
            //焰条风扇控制 B1
            case (byte)0xB1:
            {
                myMessage.messageType = MessageType.YTFan;
                unitstatus.FSZT = 1 == RxData[5];
                break;
            }
            //播撒方式 B2
            case (byte)0xB2:
            {
                myMessage.messageType = MessageType.BSFS;//播撒方式  0停用，1半旋转,2全旋转
                unitstatus.BSFS =  Byte2Int(RxData[5]);
                break;
            }
            //错误返回 44
            case(byte) 0x44:{
                myMessage.messageType = MessageType.Error;

                TempData = Byte2Int(RxData[6]) * 256;
                TempData += Byte2Int(RxData[7]);


                switch (RxData[5])
                {
                    case 0x01:
                        if (TempData == 0)
                        {
                            MyGlobal.deviceLogArrayList.add(0,new DeviceLog("请检查其他功能是否关闭，风机关闭错误", Color.RED));
                        }
                        break;
                    case 0x02:
                        if (TempData == 1)
                        {
                            MyGlobal.deviceLogArrayList.add(0,new DeviceLog("方位未归零", Color.RED)) ;
                        }
                        break;
                    case 0x03:
                        if (TempData == 1)
                        {
                            MyGlobal.deviceLogArrayList.add(0,new DeviceLog("风机未启动", Color.RED));
                        }
                        break;
                    case 0x04:
                    {
                        MyGlobal.deviceLogArrayList.add(0,new DeviceLog("水泵未开启" , Color.RED));
                    }
                    break;
                    case 0x05:
                    {
                        MyGlobal.deviceLogArrayList.add(0,new DeviceLog("系统断电错误，方位角未归零", Color.RED));
                    }
                    break;
                    case 0x06:
                            MyGlobal.deviceLogArrayList.add(0,new DeviceLog("电源模式参数错误", Color.RED));
                        break;
                    case 0x07:
                            MyGlobal.deviceLogArrayList.add(0,new DeviceLog("方位旋转超时", Color.RED));
                        break;
                    case 0x08:
                            MyGlobal.deviceLogArrayList.add(0,new DeviceLog("系统未上电", Color.RED));
                        break;
                    case 0x09:
                        MyGlobal.deviceLogArrayList.add(0,new DeviceLog("舱体冷却中，风机关闭错误! 剩余时间:="+ TempData, Color.RED));
                        break;
                    case 0x0A:
                        MyGlobal.deviceLogArrayList.add(0,new DeviceLog("方位角未旋转到加热口，加热开始中止", Color.RED));
                        break;
                    case 0x0B:
                        MyGlobal.deviceLogArrayList.add(0,new DeviceLog("方位角未旋转到焰条增雨口，焰条点火中止", Color.RED));
                        break;
                    case 0x0C:
                        MyGlobal.deviceLogArrayList.add(0,new DeviceLog("其它模式工作中或风机未启动", Color.RED));
                        break;
                    case 0x0D:
                        MyGlobal.deviceLogArrayList.add(0,new DeviceLog("水箱液位低于%3，水阀水泵自动关闭", Color.RED));
                        break;
                    case 0x0E:
                        MyGlobal.deviceLogArrayList.add(0,new DeviceLog("俯仰或方位正在转动", Color.RED));
                        break;
                    default:
                        MyGlobal.deviceLogArrayList.add(0,new DeviceLog("未定义的错误", Color.RED));
                        break;
                }
                break;
            }
        }

        Log.i("rqp-RecvDataThread-DealRecv","------------------收到 ["+myMessage.messageType.getName()+"] 消息");
        UpdateStatus();
        AddLog(myMessage.messageType);
        EventBus.getDefault().post(myMessage);
    }

    private void UpdateStatus()
    {
        MyGlobal.heartDataArrayList.clear();

        Field[] fields = MyGlobal.unitstatus.getClass().getFields();
        for(Field f : fields)
        {
            HeartData heartData = new HeartData();

            try {
                Field f2 = MyGlobal.unitstatus.getClass().getDeclaredField(f.getName());
                MyAnnotation annotation = f2.getAnnotation(MyAnnotation.class);
                if(annotation != null) {
                    heartData.Key = annotation.value();
                    heartData.Value = GetMatchValueStr(heartData.Key,f.get(MyGlobal.unitstatus));
                    MyGlobal.heartDataArrayList.add(heartData);
                }
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            } catch (NoSuchFieldException e) {
                throw new RuntimeException(e);
            }
        }

    }


    private String GetMatchValueStr(String key,Object value)
    {
        switch (key) {
            case "系统供电状态":
            case "加热状态":
            case "水泵状态":
            case "混合阀1状态":
            case "混合阀2状态":
            case "排水阀状态":
            case "防雨顶状态":
            case "风扇状态":
                return  (Boolean)value ? "开":"关";
            case "俯仰角状态":
                return  (Boolean)value ? "升起":"落下";
            case "工作模式":
                if( (int)value == 0)
                    return "空";
                if( (int)value == 1)
                    return "除雾霾加热";
                if( (int)value == 2)
                    return "消除臭氧";
                if( (int)value == 3)
                    return "人工增雨";
            case "急停状态":
                return  (Boolean)value ? "急停中":"正常";
            case "俯仰状态":
                return  (Boolean)value ? "倾斜":"垂直";
            case "加热开启模式":
                if( (int)value == 0)
                    return "未开启";
                if( (int)value == 1)
                    return "开启";
                if( (int)value == 2)
                    return "等待中";
            case "供电方式":
                if( (int)value == 0)
                    return "无选择";
                if( (int)value == 1)
                    return "市电";
                if( (int)value == 2)
                    return "发电机";
            case "系统上电时间":
                return  cal((int)value);
            case "播撒方式":
                if( (int)value == 0)
                    return "定向播撒";
                if( (int)value == 1)
                    return "摇摆播撒";
                if( (int)value == 2)
                    return "圆周播撒";
            case "启动方式":
                if( (int)value == 0)
                    return "软件启动";
                if( (int)value == 1)
                    return "硬件启动";

        }
        if(value instanceof Float)
        {
            return (new DecimalFormat(".0")).format(value);
        }
        else if(value instanceof  Double)
        {
            return value.toString();
        }
        return value.toString();
    }
    public String cal(int second) {
        int h = 0;
        int d = 0;
        int s = 0;
        int temp = second % 3600;
        if (second > 3600) {
            h = second / 3600;
            if (temp != 0) {
                if (temp > 60) {
                    d = temp / 60;
                    if (temp % 60 != 0) {
                        s = temp % 60;
                    }
                } else {
                    s = temp;
                }
            }
        } else {
            d = second / 60;
            if (second % 60 != 0) {
                s = second % 60;
            }
        }
        return h + "时" + d + "分" + s + "秒";
    }

    private void AddLog(MessageType messageType)
    {
        String msg = "收到: ["+messageType.getName()+"] 命令回复";

        switch (messageType) {
            case Heart:
                MyGlobal.AddLog("收到心跳信息",Color.BLUE);
                break;
            case SysPower:
                MyGlobal.AddLog(msg + ( MyGlobal.unitstatus.SDZT ? "开":"关"),Color.BLUE);
                break;
            case FYD:
                MyGlobal.AddLog(msg + ( MyGlobal.unitstatus.FYDZT ? "开":"关"),Color.BLUE);
                break;
            case FJPL:

                MyGlobal.AddLog(msg + ( MyGlobal.unitstatus.FJPL > 0 ? "开":"关"),Color.BLUE);
                break;
            case JRKZ:
                MyGlobal.AddLog(msg + ( MyGlobal.unitstatus.JRZT ? "开":"关"),Color.BLUE);
                break;
            case FireReset:
                MyGlobal.AddLog(msg + "复位成功",Color.BLUE);
                break;
            case FireState:
                MyGlobal.AddLog(msg + "巡检完成",Color.BLUE);
                break;
            case FWJ:
                MyGlobal.AddLog(msg + "方位角调整完成 方位角:="+MyGlobal.unitstatus.FWJ,Color.BLUE);
                break;
            case FYJZT:
                MyGlobal.AddLog(msg + ( MyGlobal.unitstatus.FYZT ? "倾斜":"垂直"),Color.BLUE);
                break;
            case SB:
                MyGlobal.AddLog(msg + ( MyGlobal.unitstatus.SBZT ? "开":"关"),Color.BLUE);
                break;
            case HHF1:
                MyGlobal.AddLog(msg + ( MyGlobal.unitstatus.HHF1ZT ? "开":"关"),Color.BLUE);
                break;
            case HHF2:
                MyGlobal.AddLog(msg + ( MyGlobal.unitstatus.HHF2ZT ? "开":"关"),Color.BLUE);
                break;
            case PSF:
                MyGlobal.AddLog(msg + ( MyGlobal.unitstatus.PSFZT ? "开":"关"),Color.BLUE);
                break;
            case YTFan:
                MyGlobal.AddLog(msg + ( MyGlobal.unitstatus.FSZT ? "开":"关"),Color.BLUE);
                break;
            case BSFS://播撒方式 0停用，1半旋转,2全旋转
                if(MyGlobal.unitstatus.BSFS==0)
                    MyGlobal.AddLog(msg + "停止",Color.BLUE);
                else  if(MyGlobal.unitstatus.BSFS==1)
                    MyGlobal.AddLog(msg + "半旋转",Color.BLUE);
                else if(MyGlobal.unitstatus.BSFS==2)
                    MyGlobal.AddLog(msg + "全旋转",Color.BLUE);
                break;
            case AlarmStop:
                MyGlobal.AddLog(msg + ( MyGlobal.unitstatus.AlarmStop ? "开":"关"),Color.BLUE);
                break;
            default:MyGlobal.AddLog(msg ,Color.BLUE);

        }
    }
}
